package com.ebupt.migu.music.common.utils;

import java.util.*;

import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import com.ebupt.migu.restapi.EsRestHttp;

import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONObject;
import lombok.extern.slf4j.Slf4j;

/**
 * 查询ES结果集
 *
 * @author liuyangyang@cd.ebupt.com
 */
@Slf4j
@Component
public class ESearch {
    @Value("${spring.elasticsearch.alias}")
    private String ES_ALIAS;

    /**
     * 过滤标签及返回反查结果
     *
     * @param criteria
     * @param type 文件类型：1-手机号；2-IMEI/IDFA；3-UID；
     * @param onlySMS 仅用于短信运营：0-否；1-是；
     * @param age
     * @param sex
     * @param system
     * @param area
     * @return
     */
    public Map<String, Object> analysis(String criteria, String type, String onlySMS, List<String> age,
        List<String> sex, List<String> system, List<String> area) {
        Map<String, Object> result = new HashMap<>();
        // 反查结果集
        Set<String> msisdns = new HashSet<>();
        Set<String> imeis = new HashSet<>();
        Set<String> uids = new HashSet<>();
        boolean legal = true;
        // ES查询条件
        String criteria_ = "";
        // 文件类型：1-手机号；2-IMEI/IDFA；3-UID；
        switch (type) {
            case "1":
                if (PatternVer.isMsisdn(criteria)) {
                    criteria_ = "msisdn:" + criteria;
                    break;
                } else {
                    log.info("号码验证未通过：{}", criteria);
                    return null;
                }
            case "2":
                if (criteria.contains("-")) {
                    criteria_ = "idfa:" + criteria;
                    break;
                } else {
                    criteria_ = "imei:" + criteria;
                    break;
                }
            case "3":
                criteria_ = "uid:" + criteria;
                break;
        }
        EsRestHttp er = new EsRestHttp();
        String esResult = er.search(ES_ALIAS, criteria_, 1);
        JSONObject jsonObject = new JSONObject(esResult);
        JSONArray hits = (JSONArray)jsonObject.getByPath("hits.hits");
        Integer size = hits.size();
        for (int i = 0; i < size; i++) {
            Object obj = hits.get(i);
            String uid = CommonUtil.getElement(obj, "_source.uid");
            String msisdn = CommonUtil.getElement(obj, "_source.msisdn");
            String idfa = CommonUtil.getElement(obj, "_source.idfa");
            String imei = CommonUtil.getElement(obj, "_source.imei");
            String sex_ = CommonUtil.getElement(obj, "_source.sex");
            String age_ = CommonUtil.getElement(obj, "_source.age");
            String provName = CommonUtil.getElement(obj, "_source.prov_name");
            String areaName = CommonUtil.getElement(obj, "_source.area_name");
            String phoneSys = CommonUtil.getElement(obj, "_source.phone_system");
            boolean aim = true;
            switch (type) {
                case "1":
                    if (StringUtils.isBlank(msisdn) || !msisdn.equals(criteria)) {
                        aim = false;
                        break;
                    }
                case "2":
                    if (criteria.contains("-")) {
                        if (StringUtils.isBlank(idfa) || !idfa.equals(criteria)) {
                            aim = false;
                            break;
                        }
                    } else {
                        if (StringUtils.isBlank(imei) || !imei.equals(criteria)) {
                            aim = false;
                            break;
                        }
                    }
                case "3":
                    if (StringUtils.isBlank(uid) || !uid.equals(criteria)) {
                        aim = false;
                        break;
                    }
            }
            if (aim == false) {
                continue;
            }
            if (!CommonUtil.isContains(sex, sex_)) {
                log.info("校验未通过：{}-性别不符合要求", criteria);
                continue;
            }
            if (!CommonUtil.isContains(age, age_)) {
                log.info("校验未通过：{}-年龄不符合要求", criteria);
                continue;
            }
            if (!CommonUtil.isContains(area, provName) && !CommonUtil.isContains(area, areaName)) {
                log.info("校验未通过：{}-省市不符合要求", criteria);
                continue;
            }
            if (!CommonUtil.isContains(system, phoneSys)) {
                log.info("校验未通过：{}-操作系统不符合要求", criteria);
                continue;
            }
            // 仅用于短信运营：0-否；1-是；
            if ("0".equals(onlySMS)) {
                if (!"".equals(uid)) {
                    uids.add(uid);
                }

                if (!"".equals(idfa)) {
                    imeis.add(idfa);
                } else if (!"".equals(imei)) {
                    imeis.add(imei);
                }
            }
            if (!"".equals(msisdn) && PatternVer.isMsisdn(msisdn)) {
                msisdns.add(msisdn);
            }
        }
        result.put("msisdns", msisdns);
        result.put("uids", uids);
        result.put("imeis", imeis);
        return result;
    }

    /**
     * 过滤标签及返回反查结果
     *
     * @param criteria
     * @param type 文件类型：1-手机号；2-IMEI/IDFA；3-UID；
     * @param onlySMS 仅用于短信运营：0-否；1-是；
     * @return
     */
    public Map<String, Object> analysis2(String criteria, String type, String onlySMS, List<String> age,
        List<String> sex, List<String> system, List<String> area) {
        Map<String, Object> result = new HashMap<>();
        // 反查结果集
        Set<String> msisdns = new HashSet<>();
        Set<String> imeis = new HashSet<>();
        Set<String> uids = new HashSet<>();
        boolean legal = true;
        // ES查询条件
        String criteria_ = "";
        // 文件类型：1-手机号；2-IMEI/IDFA；3-UID；
        switch (type) {
            case "1":
                if (PatternVer.isMsisdn(criteria)) {
                    criteria_ = "msisdn:" + criteria;
                    break;
                } else {
                    log.info("号码验证未通过：{}", criteria);
                    return null;
                }
            case "2":
                if (criteria.contains("-")) {
                    criteria_ = "idfa:" + criteria;
                    break;
                } else {
                    criteria_ = "imei:" + criteria;
                    break;
                }
            case "3":
                criteria_ = "uid:" + criteria;
                break;
        }
        EsRestHttp er = new EsRestHttp();
        String esResult = er.search(ES_ALIAS, criteria_, 1);
        JSONObject jsonObject = new JSONObject(esResult);
        JSONArray hits = (JSONArray)jsonObject.getByPath("hits.hits");
        Integer size = hits.size();
        for (int i = 0; i < size; i++) {
            Object obj = hits.get(i);
            String uid = CommonUtil.getElement(obj, "_source.uid");
            String msisdn = CommonUtil.getElement(obj, "_source.msisdn");
            String idfa = CommonUtil.getElement(obj, "_source.idfa");
            String imei = CommonUtil.getElement(obj, "_source.imei");
            String sex_ = CommonUtil.getElement(obj, "_source.sex");
            String age_ = CommonUtil.getElement(obj, "_source.age");
            String provName = CommonUtil.getElement(obj, "_source.prov_name");
            String areaName = CommonUtil.getElement(obj, "_source.area_name");
            String phoneSys = CommonUtil.getElement(obj, "_source.phone_system");
            if (!CommonUtil.isContains(sex, sex_)) {
                log.info("校验未通过：{}-性别不符合要求", criteria);
                continue;
            }
            if (!CommonUtil.isContains(age, age_)) {
                log.info("校验未通过：{}-年龄不符合要求", criteria);
                continue;
            }
            if (!CommonUtil.isContains(area, provName) && !CommonUtil.isContains(area, areaName)) {
                log.info("校验未通过：{}-省市不符合要求", criteria);
                continue;
            }
            if (!CommonUtil.isContains(system, phoneSys)) {
                log.info("校验未通过：{}-操作系统不符合要求", criteria);
                continue;
            }
            // 仅用于短信运营：0-否；1-是；
            if ("0".equals(onlySMS)) {
                if (!"".equals(uid)) {
                    uids.add(uid);
                }

                if (!"".equals(idfa)) {
                    imeis.add(idfa);
                } else if (!"".equals(imei)) {
                    imeis.add(imei);
                }
            }
            if (!"".equals(msisdn) && PatternVer.isMsisdn(msisdn)) {
                msisdns.add(msisdn);
            }
        }
        switch (type) {
            case "1":
                msisdns.add(criteria);
                break;
            case "2":
                imeis.add(criteria);
                break;
            case "3":
                uids.add(criteria);
                break;
        }
        result.put("msisdns", msisdns);
        result.put("uids", uids);
        result.put("imeis", imeis);
        return result;
    }

    public Set<String> uid(String msisdn) {
        Set<String> uids = new HashSet<>();
        // ES查询条件
        String criteria_ = "msisdn:" + msisdn;
        EsRestHttp er = new EsRestHttp();
        String esResult = er.search(ES_ALIAS, criteria_, 1);
        JSONObject jsonObject = new JSONObject(esResult);
        JSONArray hits = (JSONArray)jsonObject.getByPath("hits.hits");
        Integer size = hits.size();
        for (int i = 0; i < size; i++) {
            Object obj = hits.get(i);
            String uid = CommonUtil.getElement(obj, "_source.uid");
            uids.add(uid);
        }
        return uids;
    }
}
